/**
 * 
 */
package lex.proxyverfier.verifier;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Formatter;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.lex.net.proxy.ProxyServer;
import org.lex.utils.Codec;

import lex.proxyverfier.ProxyVerifier;
import lex.proxyverfier.SpeedFormat;

/**
 * @author Daniel Liu
 */
public class ProxyServerVerifier {
	private ProxyServer proxy = null;
	private URL url = null;
	private InputStream in = null;

	public ProxyServerVerifier(ProxyServer proxy, URL url) {
		this.proxy = proxy;
		this.url = url;
	}

	public long getReadSpeed() {
		if (null == in)
			return -1L;
		SpeedCalculator sc = new SpeedCalculator();
		long speed = sc.calculateSpeed(in);
		ProxyVerifier.getApplication().getFormatter().format("%s speed: %s%n", proxy.toString(), SpeedFormat.format(speed));
		return speed;
	}

	/**
	 * @return true if the proxy works, otherwise return false
	 */
	public boolean verify()
	{
		Formatter out = ProxyVerifier.getApplication().getFormatter();
		String urlStr = url.toString();
		String name = '[' + proxy.getName() + ']';
		out.format( "%s: Try to connect %s via %s%n", name, urlStr, Codec.encodeProxy( proxy
			.getProxy() ) );
		URLConnection con = null;
		try
		{
			con = url.openConnection( proxy.getProxy() );
			con.connect();
		}
		catch( IOException e )
		{
			out.format( "%s: Connection failed to %s.%n", name, urlStr );
			return false;
		}
		Map<String, List<String>> headers = con.getHeaderFields();
		out.format( "%s: %s Headers:%n", name, urlStr );
		Set<String> keys = headers.keySet();
		for( String key : keys )
			out.format( "\t%s: %s%n", key, headers.get( key ).toString() );
		out.format( "%s: Try to read content from %s ...%n", name, urlStr );
		try
		{
			in = con.getInputStream();
		}
		catch( IOException e )
		{
			out.format( "%s: Failed to read %s%n", name, urlStr );
			in = null;
			return false;
		}
		return true;
	}
}
